package com.mrlv.common.utils;

import cn.hutool.core.date.DateTime;

import java.io.*;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author lvshiyu
 * @description: TODO
 * @date 2022年04月26日 16:01
 */
public class LogToSqlMain {
    private static String SELECT = "SELECT";
    private static String UPDATE = "UPDATE";
    private static String DELETE = "DELETE";
    private static String INSERT = "INSERT";
    private static String ALL = "ALL";

    private static String one = "Preparing: ";

    public static void main(String[] args) {
        new LogToSqlMain().parse(new String[]{"D:\\0242000271\\Desktop\\WechatTable", ALL});
    }

    public void test(File logFile) {
        // get file
        // initialized io
        // parse log to sql

        // format sql
        // generate sql file
        // invoke jdbc
    }

    public void parse(String[] args) {
        String args0 = null;
        String args1 = null;
        if (args == null) {
            return;
        }
        if (args != null && args.length == 1) {
            args0 = args[0];
        }
        if (args != null && args.length == 2) {
            args0 = args[0];
            args1 = args[1];
            if (!args1.equalsIgnoreCase(ALL) && !args1.equalsIgnoreCase(SELECT)
                    && !args1.equalsIgnoreCase(UPDATE) && !args1.equalsIgnoreCase(DELETE)
                    && !args1.equalsIgnoreCase(INSERT)) {
                return;
            }
        }

        BufferedReader buffer_reader = null;
        String sql_type = null;
        try {
            File file = new File(args0);
            File[] filesOfDirs = file.listFiles();
            if (!file.isDirectory() || filesOfDirs.length == 0) {
                System.out.println("invalid path or io error");
                return;
            }
            String temp_read = null;
            String strTemp = null;
            String strTimeStamp = null;
            Long log_Line_Num = 0L;
            Map<String, String> map = null;
            for (int i = 0; i < filesOfDirs.length; i++) {
                Boolean flag = getSqlMode(args1, filesOfDirs[i].getName());
                flag = true;
                if (flag) {
                    File tmp_File = filesOfDirs[i].getAbsoluteFile();
                    File file_2 = new File(filesOfDirs[i].getName().replace(".log", ".sql"));
                    file_2.createNewFile();
                    sql_type = getSQLType(tmp_File);
                    buffer_reader = new BufferedReader(new FileReader(tmp_File));
                    BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file_2));
                    temp_read = buffer_reader.readLine();
                    while (temp_read != null) {
                        // validate every line should be SQL
                        if (temp_read.contains("2022-04-19 22:58:54,489")) {
                            System.out.println("");
                        }
                        if (validateFileLine(temp_read, INSERT)) {
                            map = new HashMap<>();
                            map.put("sql", temp_read.substring(temp_read.indexOf("Preparing: ") + "Preparing: ".length()).replace("?", "%s"));
                            map.put("prrix", temp_read.substring(temp_read.indexOf("DEBUG"), temp_read.indexOf(" Preparing: ")));
                        }
                        if (map != null && temp_read.contains(map.get("prrix") + "Parameters:")) {
                            String substring = temp_read.substring(temp_read.indexOf("Parameters: ") + "Parameters: ".length());
                            List<String> collect = Arrays.stream(substring.split( "\\), ")).map(e -> {
                                if (')' != e.charAt(e.length() - 1)) {
                                    e += ")";
                                }
                                int typeStart = e.lastIndexOf("(");
                                String type = e.substring(typeStart + 1, e.length() - 1);
                                String value = e.substring(0, typeStart);
                                if (type.equals("String")) {
                                    return "'" + value + "'";
                                } else if(type.equals("Timestamp")) {
                                    return DateTime.of(value, "yyyy-MM-dd HH:mm:ss.SSS").toString("yyyyMMddHHmmss");
                                } else {
                                    return value;
                                }
                            }).collect(Collectors.toList());
                            if (map.get("sql").contains("INSERT INTO t_wechat_order")) {
                                System.out.println(String.format(map.get("sql"), collect.toArray()) + ";");
                            }
                            bufferedWriter.flush();
                            bufferedWriter.write(String.format(map.get("sql"), collect.toArray()) + ";");

                            log_Line_Num++;
                            map = null;
                        }
                        temp_read = buffer_reader.readLine();
                    }
                    buffer_reader.close();
                    bufferedWriter.close();
                }
            }
            System.out.println(log_Line_Num);
        } catch (NumberFormatException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (buffer_reader != null) {
                try {
                    buffer_reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    private boolean validateFileLine(String str_Line, String sql_type) {
        if (sql_type.equals(INSERT)) {
            if (str_Line.toUpperCase().contains("INTO")
                    && str_Line.toUpperCase().contains("VALUES"))
                return true;
        } else if (sql_type.equals(SELECT)) {
            if (str_Line.toUpperCase().contains("FROM")
                    && str_Line.toUpperCase().contains("WHERE")) {
                return true;
            }
        } else if (sql_type.equals(UPDATE)) {
            if (str_Line.toUpperCase().contains("SET")
                    && str_Line.toUpperCase().contains("WHERE")) {
                return true;
            }
        } else if (sql_type.equals(DELETE)) {
            if (str_Line.toUpperCase().contains("WHERE")) {
                return true;
            }
        }
        return false;
    }

    private String getSQLType(File file) {
        if (file.getName().toUpperCase().contains(SELECT)) {
            return SELECT;
        } else if (file.getName().toUpperCase().contains(UPDATE)) {
            return UPDATE;
        } else if (file.getName().toUpperCase().contains(DELETE)) {
            return DELETE;
        } else if (file.getName().toUpperCase().contains(INSERT)) {
            return INSERT;
        }
        return null;
    }

    public boolean getSqlMode(String args, String fileName) {
        if (args == null || ALL.equalsIgnoreCase(args))
            return (fileName.startsWith(INSERT) || fileName.startsWith(DELETE)
                    || fileName.startsWith(UPDATE) || fileName
                    .startsWith(SELECT));
        if ((SELECT).equalsIgnoreCase(args)) {
            return (fileName.startsWith(SELECT));
        } else if ((UPDATE).equalsIgnoreCase(args)) {
            return (fileName.startsWith(UPDATE));
        } else if ((INSERT).equalsIgnoreCase(args)) {
            return (fileName.startsWith(INSERT));
        } else if ((DELETE).equalsIgnoreCase(args)) {
            return (fileName.startsWith(DELETE));
        }
        return false;
    }
}